package org.example.es.configuration;

import org.elasticsearch.action.search.*;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.util.Arrays;

/**
 * @author Tang
 * @classname SearchApis
 * @description [ https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.7/java-rest-high-search.html#java-rest-high-search-async ]
 * @date 2023/4/22 16:56
 */
public class SearchApis {

    public static void main(String[] args) throws Exception{
        final RestHighLevelClient client = new EsConfiguration().restHighLevelClient();

        final SearchApis searchApis = new SearchApis();
        searchApis.scrollIndex(client);

        client.close();
    }


    public void scrollIndex(RestHighLevelClient client) throws Exception{

        SearchRequest searchRequest = new SearchRequest("users");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//        searchSourceBuilder.query()
        searchSourceBuilder.size(10);
        searchRequest.source(searchSourceBuilder);

        Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
        searchRequest.scroll(scroll);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        String scrollId = searchResponse.getScrollId();
        SearchHits hits = searchResponse.getHits();
        System.out.println("result:" + hits);
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        while (searchHits != null && searchHits.length > 0) {

            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(scroll);
            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            scrollId = searchResponse.getScrollId();
            searchHits = searchResponse.getHits().getHits();

            System.out.println("result:" + Arrays.toString(searchHits));
        }

        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
        boolean succeeded = clearScrollResponse.isSucceeded();

    }

    public void searchIndex(RestHighLevelClient client) throws Exception{
        SearchRequest searchRequest = new SearchRequest("users");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//        searchSourceBuilder.from(10).size(20);

        searchRequest.source(searchSourceBuilder);
        final SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(response.toString());
    }

    /**
     * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.7/java-rest-high-aggregation-builders.html
     * @param client client
     * @throws Exception
     */
    public void aggregationIndex(RestHighLevelClient client) throws Exception{
        SearchRequest searchRequest = new SearchRequest("users");
        // 查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.sort("age", SortOrder.ASC).size(0);

        // 聚合条件
        final FilterAggregationBuilder filterAggregationBuilder = AggregationBuilders.filter("name_f", QueryBuilders.termQuery("name", "tang"));
        final AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("age_age").field("age");
        filterAggregationBuilder.subAggregation(avgAggregationBuilder);

        searchSourceBuilder.aggregation(filterAggregationBuilder);
        searchRequest.source(searchSourceBuilder);

        System.out.println(searchSourceBuilder.toString());

        final SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(response.toString());
    }

}
